package com.fitbet.entity.trading;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

import com.demo2do.core.format.PersistentFormat;
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.JsonIdentityReference;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import com.fitbet.entity.bet.UserBet;
import com.fitbet.entity.bet.UserBetSupport;
import com.fitbet.entity.user.User;

/**
 * 
 * @author mohanlan
 *
 */
@Entity
@Table(name = "sales_order")
@PersistentFormat
@JsonIgnoreProperties(value={"hibernate_lazy_initializer","handler","fieldHandler"})
public class SalesOrder {
    
    @Id
    @GeneratedValue
    private Long id;
    
    /**
     * 订单编号
     */
    private String code;
    
    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id")
    @JsonIdentityReference(alwaysAsId=true)
    private User user;
    
    @Enumerated(EnumType.ORDINAL)
    private OrderType type;
    
    /**
     * 所属userBet
     */
    @ManyToOne(optional = true, fetch = FetchType.LAZY)
    @JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id")
    @JsonIdentityReference(alwaysAsId=true)
    private UserBet userBet;
    
    /**
     * 所属userBet
     */
    @ManyToOne(optional = true, fetch = FetchType.LAZY)
    @JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id")
    @JsonIdentityReference(alwaysAsId=true)
    private UserBetSupport userBetSupport;
    
    /**
     * 下单人手机
     */
    private String mobile;
    
    /**
     * 下单人昵称
     */
    private String nickname;
    
    /**
     * 订单描述
     */
    private String content;
    
    /**
     * 订单金额
     */
    private int price;
    
    /**
     * 实际已支付金额
     */
    private int paidPrice;
    
    private Date createTime;
    
    /**
     * 订单状态
     * 已创建/进行中/已结束/用户取消/系统取消
     */
    @Enumerated(EnumType.STRING)
    private OrderStatus status;
    
    /**
     * 支付时间
     */
    private Date payTime;
    
    /**
     * 订单支付状态
     * 待支付/已支付/已退款
     */
    @Enumerated(EnumType.STRING)
    private PaymentStatus paymentStatus;
    
    @Column(name = "is_disabled")
    private boolean disabled;
    
    /**
     * The default constructor
     */
    public SalesOrder() {
    }
    
    /**
     * 大赌局订单创建
     * 
     * @param userBet
     */
    public SalesOrder(UserBet userBet) {
        this.type = OrderType.BET;
        this.userBet = userBet;
        this.user = userBet.getUser();
        this.code = "B" + userBet.getBet().getId() + this.user.getId() + + System.currentTimeMillis();
        this.mobile = this.user.getMobile();
        this.nickname = this.user.getNickname();
        this.content = this.user.getNickname() + "参与挑战【" + userBet.getBet().getName() + "】"; 
        this.price = 20000;  // FIXME
        this.paidPrice = 0;
        this.status = OrderStatus.CREATED;
        this.paymentStatus = PaymentStatus.PENDING;
        this.createTime = new Date();
        this.disabled = false;
    }
    
    /**
     * 小赌局订单创建
     * 
     * @param userBet
     */
    public SalesOrder(UserBetSupport userBetSupport) {
        this.type = OrderType.BET_SUPPORT;
        this.userBet = userBetSupport.getUserBet();
        this.userBetSupport = userBetSupport;
        this.user = userBetSupport.getUser();
        this.code = "B" + userBetSupport.getBet().getId() + userBetSupport.getUserBet().getId() + this.user.getId() + + System.currentTimeMillis();
        this.mobile = this.user.getMobile();
        this.nickname = this.user.getNickname();
        this.content = "参与竞猜用户的挑战【" + userBet.getBet().getName() + "】"; 
        this.price = 10000;  // FIXME
        this.paidPrice = 0;
        this.status = OrderStatus.CREATED;
        this.paymentStatus = PaymentStatus.PENDING;
        this.createTime = new Date();
        this.disabled = false;
    }
    
    /**
     * 
     * @return
     */
    public SalesOrder paid() {
        this.paidPrice = this.price;
        this.paymentStatus = PaymentStatus.PAID;
        this.payTime = new Date();
        this.status = OrderStatus.PROCESSING;
        
        return this;
    }
    
    /**
     * @return the id
     */
    public Long getId() {
        return id;
    }

    /**
     * @return the code
     */
    public String getCode() {
        return code;
    }

    /**
     * @return the user
     */
    public User getUser() {
        return user;
    }

    /**
     * @return the type
     */
    public OrderType getType() {
        return type;
    }

    /**
     * @return the userBet
     */
    public UserBet getUserBet() {
        return userBet;
    }

    /**
     * @return the userBetSupport
     */
    public UserBetSupport getUserBetSupport() {
        return userBetSupport;
    }

    /**
     * @return the mobile
     */
    public String getMobile() {
        return mobile;
    }

    /**
     * @return the nickname
     */
    public String getNickname() {
        return nickname;
    }

    /**
     * @return the content
     */
    public String getContent() {
        return content;
    }

    /**
     * @return the price
     */
    public int getPrice() {
        return price;
    }

    /**
     * @return the paidPrice
     */
    public int getPaidPrice() {
        return paidPrice;
    }

    /**
     * @return the createTime
     */
    public Date getCreateTime() {
        return createTime;
    }

    /**
     * @return the status
     */
    public OrderStatus getStatus() {
        return status;
    }

    /**
     * @return the payTime
     */
    public Date getPayTime() {
        return payTime;
    }

    /**
     * @return the paymentStatus
     */
    public PaymentStatus getPaymentStatus() {
        return paymentStatus;
    }

    /**
     * @return the disabled
     */
    public boolean isDisabled() {
        return disabled;
    }

    /**
     * @param id the id to set
     */
    public void setId(Long id) {
        this.id = id;
    }

    /**
     * @param code the code to set
     */
    public void setCode(String code) {
        this.code = code;
    }

    /**
     * @param user the user to set
     */
    public void setUser(User user) {
        this.user = user;
    }

    /**
     * @param type the type to set
     */
    public void setType(OrderType type) {
        this.type = type;
    }

    /**
     * @param userBet the userBet to set
     */
    public void setUserBet(UserBet userBet) {
        this.userBet = userBet;
    }

    /**
     * @param userBetSupport the userBetSupport to set
     */
    public void setUserBetSupport(UserBetSupport userBetSupport) {
        this.userBetSupport = userBetSupport;
    }

    /**
     * @param mobile the mobile to set
     */
    public void setMobile(String mobile) {
        this.mobile = mobile;
    }

    /**
     * @param nickname the nickname to set
     */
    public void setNickname(String nickname) {
        this.nickname = nickname;
    }

    /**
     * @param content the content to set
     */
    public void setContent(String content) {
        this.content = content;
    }

    /**
     * @param price the price to set
     */
    public void setPrice(int price) {
        this.price = price;
    }

    /**
     * @param paidPrice the paidPrice to set
     */
    public void setPaidPrice(int paidPrice) {
        this.paidPrice = paidPrice;
    }

    /**
     * @param createTime the createTime to set
     */
    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    /**
     * @param status the status to set
     */
    public void setStatus(OrderStatus status) {
        this.status = status;
    }

    /**
     * @param payTime the payTime to set
     */
    public void setPayTime(Date payTime) {
        this.payTime = payTime;
    }

    /**
     * @param paymentStatus the paymentStatus to set
     */
    public void setPaymentStatus(PaymentStatus paymentStatus) {
        this.paymentStatus = paymentStatus;
    }

    /**
     * @param disabled the disabled to set
     */
    public void setDisabled(boolean disabled) {
        this.disabled = disabled;
    }
}
